package com.example.gcmtest1.youtube;

import java.io.InputStream;
import java.net.URI;
import java.net.URLEncoder;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.example.gcmtest1.MySqlHelper;
import com.example.gcmtest1.R;
import com.example.gcmtest1.YoutubeActivity;
import com.example.gcmtest1.httpserver.HTTPProxyService;

import android.content.Context;
import android.net.Uri;
import android.net.UrlQuerySanitizer;
import android.net.UrlQuerySanitizer.ParameterValuePair;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

public class SmartHTTPDownload {

	private String logName = "SmartHTTPDownload";
	private String url;
	private Uri uri;
	private String host;
	private String originalUrl;
	private Context context;
	private YoutubeDownloader parent;
	
	private String fileName = "";
	private View rowView;
    private TextView lblFileName;
    public TextView lblFileSize;
    public ProgressBar pgbFileDownload;
    private LinearLayout layoutDownload1;
	private ViewGroup parentView;
	
	private int contentLength;
	private YoutubeSQLRecord sqlRecord;
	
	public SmartHTTPDownload(Context context, String url) {
		this.context = context;
		this.originalUrl = url;
		this.uri = Uri.parse(url);
		
		Log.d(logName, "url=" + this.originalUrl);
		
		this.host = this.uri.getHost();
		
		Log.d(logName, "host=" + host);
		Log.d(logName, "scheme=" + this.uri.getScheme());
		Log.d(logName, "query=" + this.uri.getQuery());
		
		UrlQuerySanitizer q = new UrlQuerySanitizer(url);
		StringBuffer sb = new StringBuffer();
		int i = 0;
		for (ParameterValuePair pv : q.getParameterList()) {
			
			if (i > 0) {
				sb.append("&");
			}
			
			sb.append(pv.mParameter + "=" + URLEncoder.encode(pv.mValue));
			
			i += 1;
		}
		
		this.url = this.uri.getScheme() + "://" + this.uri.getHost() + "/videoplayback?" + sb.toString();
		
		//url = URLEncoder.encode(url);

	}
	
	public void setSQLRecord(YoutubeSQLRecord r) {
		this.sqlRecord = r;
	}
	
	public YoutubeSQLRecord getSQLRecord() {
		return(this.sqlRecord);
	}
	
	public void setParentView(ViewGroup parentView) {
		this.parentView = parentView;
	}
	
	public String getFileName() {
		return(this.fileName);
	}
	
	public void setParent(YoutubeDownloader parent) {
		this.parent = parent;
	}
	
	public static String getHost(String url){
	    if(url == null || url.length() == 0)
	        return "";

	    int doubleslash = url.indexOf("//");
	    if (doubleslash == -1)
	        doubleslash = 0;
	    else
	        doubleslash += 2;

	    int end = url.indexOf('/', doubleslash);
	    end = end >= 0 ? end : url.length();

	    return url.substring(doubleslash, end);
	}
	
	public void execute(String rangeFrom, String rangeTo, String fileName) {
		this.fileName = fileName;
		String fName = YoutubeActivity.VIDEO_FOLDER + fileName;
		
		if (this.sqlRecord != null) {
			this.sqlRecord.setLastByte(Integer.valueOf(rangeFrom));
			this.sqlRecord.setFileLocation(fName);
			this.sqlRecord.setContentLength(0);
			
			MySqlHelper sqlHelper = HTTPProxyService.getInstance().sqlHelper;
			//sqlHelper.insertYoutube(this.sqlRecord);
			Log.i(logName, "inserted youtube record");
			
		}
		Log.d(logName, "downloading url:" + this.url);
		
		HttpClient httpClient = new DefaultHttpClient();
		
		HttpGet httpGet = new HttpGet(this.url);
		
		try {
			//List<NameValuePair> arrHeaders = new ArrayList<NameValuePair>();
						 
			httpGet.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpGet.addHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
			httpGet.addHeader("Accept-Encoding", "gzip,deflate,sdch");
			httpGet.addHeader("Connection", "keep-alive");
			httpGet.addHeader("Accept-Language", "th,en-US;q=0.8,en;q=0.6");
			httpGet.addHeader("Host", this.host);
			//httpGet.addHeader("Referer", this.url);
			httpGet.addHeader("Range", "bytes=" + rangeFrom + "-" + rangeTo);
			httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4");
			
			HttpResponse response = httpClient.execute(httpGet);
			
			Log.d(logName, "statusCode=" + response.getStatusLine().getStatusCode());
			
			this.contentLength = 4096;
			
			if ( (response.getStatusLine().getStatusCode() == 200) || (response.getStatusLine().getStatusCode() == 206) ) {

				for (Header h : response.getAllHeaders()) {
					Log.d(logName, h.getName() + ":" + h.getValue());
				}
				
				if (response.containsHeader("Content-Length") == true) {
					contentLength = Integer.valueOf(response.getFirstHeader("Content-Length").getValue());
					Log.d(logName, "contentLength=" + String.valueOf(contentLength));	
				}
				
			}
			
			if (this.sqlRecord != null) {
				this.sqlRecord.setContentLength(contentLength);
			}
			
			InputStream ins = response.getEntity().getContent();
			
			//String fName = this.context.getFilesDir().getAbsolutePath() + "/a.mp4";
			
			Log.d(logName, "fName=" + fName);
			MyRandomWriter writer = new MyRandomWriter(fName);
			writer.setFileSize(contentLength);
			//writer.testWrite();
			
			byte[] b = new byte[1024*1024]; 
			int position = 0;
			while (position < contentLength) {
				int len = ins.read(b);
				
				writer.write(b, 0, len);
				//Log.d(logName, "Writing " + String.valueOf(position) + " from " + String.valueOf(contentLength));
				
				position += len;
				
				if (this.lblFileSize != null) {
					//this.lblFileSize.setText(String.valueOf(position));
				}
				
				if (this.parent != null) {
					this.parent.publishProgress(position);
				}
			}
			
			
			writer.done();
			
			Log.d(logName, "done.");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
		
	public View getView(View convertView, ViewGroup parent) {
		if (this.rowView == null) {
			LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		    this.rowView = inflater.inflate(R.layout.progress_subview, parent, false);
		
		    this.pgbFileDownload = (ProgressBar) this.rowView.findViewById(R.id.pgbFileDownload);
		    this.pgbFileDownload.setMax(this.contentLength);
		    		    
		}

	    this.lblFileName = (TextView) this.rowView.findViewById(R.id.lblFileName);
	    this.lblFileSize = (TextView) this.rowView.findViewById(R.id.lblFileSize);
	    this.pgbFileDownload = (ProgressBar) this.rowView.findViewById(R.id.pgbFileDownload);
	    this.layoutDownload1 = (LinearLayout) this.rowView.findViewById(R.id.layoutDownload1);
	    
	    this.lblFileName.setText(this.fileName);
	    
	    return(rowView);
	}
	
}
